package dual;

import java.awt.Point;
import java.util.ArrayList;
import java.util.HashSet;

import sample.Edge;
import sample.Vertex;
import triangulation.Triangle;

public class DualVertex
{
	/**
	 * Each dual vertex corresponds to (has) a triangle
	 */
	public Triangle tri;

	@Override
	public int hashCode()
	{
		final int prime = 31;
		int result = 1;
		result = prime * result + ((tri == null) ? 0 : tri.hashCode());
		return result;
	}

	/**
	 * A dual vertex is leaf iff it has only 1 neighbor
	 */
	public boolean isLeaf;

	/**
	 * A dual vertex can have at most 3 neighbors.
	 */
	public int childCount;

	/**
	 * A dual vertex can have at most 3 neighbors. This list is used to store those neighbors.
	 */
	public ArrayList<DualVertex> children;

	public DualVertex(Triangle tri)
	{
		this.tri = tri;
		this.childCount = 0;
		this.children = new ArrayList<DualVertex>();
		this.isLeaf = true;
	}
	

	/**
	 * Add the given vertex to the child list. If the vertex has more than 1 child, it is no longer a leaf.
	 * 
	 * @param d
	 *            - neighboring dual vertex
	 */
	public void addChild(DualVertex d)
	{
		children.add(d);
		childCount = children.size();
		if (childCount > 1) this.isLeaf = false;
	}

	public boolean equals(Object o)
	{
		DualVertex d = (DualVertex)o;
		if (this.tri.equals(d.tri)) return true;
		return false;
	}

	/**
	 * This method checks if two dual vertices have a common edge.
	 * 
	 * @param d
	 * @return true: if they share an edge
	 */
	public boolean hasCommonEdge(DualVertex d)
	{
		for (Edge e : this.tri.getEdges())
		{
			for (Edge e2 : d.tri.getEdges())
			{
				if (e.equals(e2)) return true;
			}
		}
		return false;
	}

	public String toString()
	{
		String str = (tri + "has" + childCount + " children ");

		if (isLeaf)
			str += " (leaf)\n";
		else
			str += " (non-leaf)\n";

		for (DualVertex t : children)
			str += ("\t" + t.tri + "\n");

		return str;
	}

	public Point getCenter()
	{
		Point center = new Point();
		
		HashSet<Vertex> hashVertex = new HashSet<Vertex>();
		
		for( Edge e : tri.getEdges()){
			hashVertex.add(e.getSource());
			hashVertex.add(e.getTarget());
		}
		
		ArrayList<Vertex> vertexList = new ArrayList<Vertex>(hashVertex);
		
		Point middleOfTwo = new Point();
		
		middleOfTwo.x = (int) ((vertexList.get(0).getX()+vertexList.get(1).getX())/2);
		middleOfTwo.y = (int) ((vertexList.get(0).getY()+vertexList.get(1).getY())/2);
		
		center.x = (int) (vertexList.get(2).getX()+2*(middleOfTwo.x-vertexList.get(2).getX())/3);
		center.y = (int) (vertexList.get(2).getY()+2*(middleOfTwo.y-vertexList.get(2).getY())/3);
		
		return center;
	}
	

}
